package com.wardrobe.soa.backend.admin;

import com.wardrobe.soa.backend.operator.AdminOperatorBean;
import com.wardrobe.soa.backend.operator.AdminOperatorService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.PrincipalCollection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Set;

@Component("shiroDbRealm")
public class ShiroDbRealm extends AuthorizingRealm {
    private static final Logger logger = LoggerFactory.getLogger(ShiroDbRealm.class);

    @Resource
    private AdminOperatorService adminOperatorService;

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken)
            throws AuthenticationException {

        UsernamePasswordToken token = (UsernamePasswordToken) authcToken;

        AdminOperatorBean operator = new AdminOperatorBean();
        try {
            operator = adminOperatorService.findByUsername(token.getUsername());
        } catch (Exception e) {
            logger.error("doGetAuthenticationInfo findByUsername error:", e);
        }
        if (operator != null) {
            String password = operator.getPwd();
            SimpleAuthenticationInfo info;
            try {
                info = new SimpleAuthenticationInfo(operator.getId(), password,
                        operator.getNickName());
            } catch (AuthenticationException e) {
                logger.error("doGetAuthenticationInfo SimpleAuthenticationInfo error:", e);
                throw e;
            }
            Session session = SecurityUtils.getSubject().getSession();

            session.setAttribute(SessionConstant.LOGINUSER, operator);
            return info;
        } else {
            return null;
        }
    }

    /**
     * 授权查询回调函数, 进行鉴权但缓存中无用户的授权信息时调用.
     */

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        AdminOperatorBean operator = adminOperatorService.getCurrentUser();
        if (operator != null) {
            SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
            final Set<String> permissions = adminOperatorService.getPermissionsByOperatorId(operator);
            info.addStringPermissions(permissions);
            final Set<String> roles = adminOperatorService.getRoleStrByOperatorId(operator);
            info.addRoles(roles);
            return info;
        } else {
            return null;
        }
    }
}
